From 98506e40b1474d3e99f2757a6130fc9a19045b7d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 3 Aug 2005 14:44:19 +0000 Subject: [PATCH] On x86, Xen does not claim any serial port unless the user explicitly specifies a 'com1=' or 'com2=' configuration string. This prevents users from being surprised when Xen stops domain0 from accessing serial port registers. On ia64 we still allow serial ports to get automatically configured and locked down even if no 'com1' is specified on the command line. This maintains the default preferred by the IA64 developers. Also, the method for specifying 'use existing baud rate' has changed. Instead of specifying com1=0, you must now specify e.g., com1=auto Signed-off-by: Keir Fraser --- docs/src/user.tex | 7 +++++-- xen/arch/ia64/xensetup.c | 2 ++ xen/drivers/char/ns16550.c | 35 ++++++++++++++++++++++++++--------- xen/include/xen/serial.h | 6 +++++- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/docs/src/user.tex b/docs/src/user.tex index 32c0decde7..da41a813dc 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -1709,8 +1709,11 @@ editing \path{grub.conf}. For example: `com1=9600, 8n1, 0x408, 5' maps COM1 to a 9600-baud port, 8 data bits, no parity, 1 stop bit, I/O port base 0x408, IRQ 5. - If the I/O base and IRQ are standard (com1:0x3f8,4; - com2:0x2f8,3) then they need not be specified. + If some configuration options are standard (e.g., I/O base and IRQ), + then only a prefix of the full configuration string need be + specified. If the baud rate is pre-configured (e.g., by the + bootloader) then you can specify `auto' in place of a numeric baud + rate. \item [console=$<$specifier list$>$ ] Specify the destination for Xen console I/O. diff --git a/xen/arch/ia64/xensetup.c b/xen/arch/ia64/xensetup.c index 7bcc2e7b82..88e9fc1c19 100644 --- a/xen/arch/ia64/xensetup.c +++ b/xen/arch/ia64/xensetup.c @@ -131,12 +131,14 @@ void early_cmdline_parse(char **cmdline_p) } struct ns16550_defaults ns16550_com1 = { + .baud = BAUD_AUTO, .data_bits = 8, .parity = 'n', .stop_bits = 1 }; struct ns16550_defaults ns16550_com2 = { + .baud = BAUD_AUTO, .data_bits = 8, .parity = 'n', .stop_bits = 1 diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index 3a08bdb5cf..3a39c6c426 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -15,7 +15,12 @@ #include #include -/* Config serial port with a string ,DPS,,. */ +/* + * Configure serial port with a string ,DPS,,. + * The tail of the string can be omitted if platform defaults are sufficient. + * If the baud rate is pre-configured, perhaps by a bootloader, then 'auto' + * can be specified in place of a numeric baud rate. + */ static char opt_com1[30] = "", opt_com2[30] = ""; string_param("com1", opt_com1); string_param("com2", opt_com2); @@ -154,7 +159,7 @@ static void ns16550_init_preirq(struct serial_port *port) ns_write_reg(uart, IER, 0); /* Line control and baud-rate generator. */ - if ( uart->baud != 0 ) + if ( uart->baud != BAUD_AUTO ) { ns_write_reg(uart, LCR, lcr | LCR_DLAB); ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */ @@ -244,38 +249,50 @@ static void ns16550_parse_port_config(struct ns16550 *uart, char *conf) { int baud; + /* No user-specified configuration? */ if ( (conf == NULL) || (*conf == '\0') ) - goto config_parsed; + { + /* Some platforms may automatically probe the UART configuartion. */ + if ( uart->baud != 0 ) + goto config_parsed; + return; + } - if ( (baud = simple_strtol(conf, &conf, 10)) != 0 ) + if ( strncmp(conf, "auto", 4) == 0 ) + { + uart->baud = BAUD_AUTO; + conf += 4; + } + else if ( (baud = simple_strtoul(conf, &conf, 10)) != 0 ) uart->baud = baud; if ( *conf != ',' ) goto config_parsed; conf++; - uart->data_bits = simple_strtol(conf, &conf, 10); + uart->data_bits = simple_strtoul(conf, &conf, 10); uart->parity = parse_parity_char(*conf); conf++; - uart->stop_bits = simple_strtol(conf, &conf, 10); + uart->stop_bits = simple_strtoul(conf, &conf, 10); if ( *conf == ',' ) { conf++; - uart->io_base = simple_strtol(conf, &conf, 0); + uart->io_base = simple_strtoul(conf, &conf, 0); if ( *conf == ',' ) { conf++; - uart->irq = simple_strtol(conf, &conf, 10); + uart->irq = simple_strtoul(conf, &conf, 10); } } config_parsed: /* Sanity checks. */ - if ( (uart->baud != 0) && ((uart->baud < 1200) || (uart->baud > 115200)) ) + if ( (uart->baud != BAUD_AUTO) && + ((uart->baud < 1200) || (uart->baud > 115200)) ) PARSE_ERR("Baud rate %d outside supported range.", uart->baud); if ( (uart->data_bits < 5) || (uart->data_bits > 8) ) PARSE_ERR("%d data bits are unsupported.", uart->data_bits); diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index e36e087cef..28f11f4677 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -113,8 +113,9 @@ void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs); /* * Initialisers for individual uart drivers. */ +/* NB. Any default value can be 0 if it is unknown and must be specified. */ struct ns16550_defaults { - int baud; /* default baud rate; 0 == pre-configured */ + int baud; /* default baud rate; BAUD_AUTO == pre-configured */ int data_bits; /* default data bits (5, 6, 7 or 8) */ int parity; /* default parity (n, o, e, m or s) */ int stop_bits; /* default stop bits (1 or 2) */ @@ -123,6 +124,9 @@ struct ns16550_defaults { }; void ns16550_init(int index, struct ns16550_defaults *defaults); +/* Baud rate was pre-configured before invoking the UART driver. */ +#define BAUD_AUTO (-1) + #endif /* __XEN_SERIAL_H__ */ /* -- 2.30.2